//
//  AudioPlayerManage.m
//  caishuitong
//
//  Created by 企友软mac on 2017/6/8.
//  Copyright © 2017年 zhangxy. All rights reserved.
//

#import "AudioPlayerManage.h"
#import "HeartaxDetailController.h"
#import "AppDelegate.h"
#import "PlayerModel.h"

@interface AudioPlayerManage()<HeartaxDetailDelegate>
{
    NSTimer *progressUpdateTimer;
    BOOL _played;

    //    NSString *previousUrl;
}

@property (nonatomic, strong) NSTimer *playerTimer;
@property (strong, nonatomic) AVPlayerItem *currentItem;
@property (nonatomic, strong) AVPlayer *player;

@end

static AudioPlayerManage *playerManage = nil;
static dispatch_once_t onceToken;

@implementation AudioPlayerManage

+ (AudioPlayerManage *)playerManage{
    
    dispatch_once(&onceToken, ^{
        playerManage = [[self alloc] init];
    });
    return playerManage;
}

+(void)playerManageDealloc{
    onceToken = 0;
    // 只有置成0,GCD才会认为它从未执行过.它默认为0.这样才能保证下次再次调用shareInstance的时候,再次创建对象.
    playerManage = nil;
}


- (instancetype)init {
    if (self = [super init]) {
        
    }
    return self;
}


- (NSArray *)arrPlayList {

    _arrPlayList = [WShareUtil sharedData].arrPlayList;
    return _arrPlayList;
}

- (void)audioPlayerPause {
    [_player pause];
    
    if (self.playerTimer) {
        [self.playerTimer invalidate];
        self.playerTimer = nil;
    }
    
    [WShareUtil sharedData].isPlay = NO;
}

-(NSURL *)urlOfCurrentlyPlayingInPlayer:(AVPlayer *)player{
    // get current asset
    AVAsset *currentPlayerAsset = player.currentItem.asset;
    // make sure the current asset is an AVURLAsset
    if (![currentPlayerAsset isKindOfClass:AVURLAsset.class]) return nil;
    // return the NSURL
    return [(AVURLAsset *)currentPlayerAsset URL];
}

- (void)audioPlayerPlay {
    
    AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    
    if ([WShareUtil sharedData].arrPlayList >= 0 || [WShareUtil sharedData].arrPlayList != nil) {
      
        if (!(_currentIndex > [WShareUtil sharedData].arrPlayList.count || _currentIndex < 0)) {
            
            appDelegate.wWindow.playTool.lbPlayTit.titleStr = [[WShareUtil sharedData].arrPlayList[_currentIndex] strTitle];
        }
    }
    
    [appDelegate.wWindow.playTool.lbPlayTit show];
    
    if (self.playerTimer == nil) {
        self.playerTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(playProgressAction)userInfo:nil repeats:YES];
    }
    
    NSURL *previousUrl = [self urlOfCurrentlyPlayingInPlayer:_player];

    if ([previousUrl.absoluteString isEqualToString:self.currentUrl] && ![WShareUtil strNilOrEmpty:previousUrl.absoluteString]) {
        
        if (_player != nil && _currentItem != nil) {
            [_player play];
            [SVProgressHUD dismiss];
            return;
        }
        return;
    }
    
    NSURL *url  = [NSURL URLWithString:self.currentUrl];
    
    _currentItem = [[AVPlayerItem alloc]initWithURL:url];

    if (_player != nil) {
        
        [self removeObserverAndNotificationCenter];
        [_player replaceCurrentItemWithPlayerItem:_currentItem];

    }else {
        _player = [[AVPlayer alloc]initWithPlayerItem:_currentItem];
    }
    [self addObserverAndNotificationCenter];
    [_player play];

}

- (void)audioPlayerPlayNext {
    
    if (self.arrPlayList.count <= 0 || self.arrPlayList == nil) {
        
//        [WShareUtil showAlert:@"温馨提示" delegate:nil message:@"此页面不支持列表播放"];
        return;
    }
    
    if (self.arrPlayList.count - 1 <= _currentIndex) {
        
        [WShareUtil showAlert:@"温馨提示" message:@"已经到最后一首"];
        
        WLog(@"已经到最后一首");
        return;
    }
    
    [_player pause];
    
    [self removeObserverAndNotificationCenter];
    
    AVPlayerItem *nextItem= [[AVPlayerItem alloc]initWithURL:[NSURL URLWithString:[self.arrPlayList[++_currentIndex] audio_src]]];

    [_player replaceCurrentItemWithPlayerItem:nextItem];

    [self addObserverAndNotificationCenter];

    [_player play];
    
    AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    
    if ([WShareUtil sharedData].arrPlayList >= 0 || [WShareUtil sharedData].arrPlayList != nil) {
        
        if (_currentIndex > [WShareUtil sharedData].arrPlayList.count || _currentIndex < 0) {
            return;
        }

        appDelegate.wWindow.playTool.lbPlayTit.titleStr = [[WShareUtil sharedData].arrPlayList[_currentIndex] strTitle];
        
    }
    
    [appDelegate.wWindow.playTool.lbPlayTit show];

}

- (void)audioPlayerPlayPrevious {
    
    if (self.arrPlayList.count <= 0 || self.arrPlayList == nil) {
//        [WShareUtil showAlert:@"温馨提示" delegate:nil message:@"此页面不支持列表播放"];
        return;
    }
    
    if (_currentIndex <= 0) {
        
        [WShareUtil showAlert:@"温馨提示" message:@"已经到第一首"];
        return;
    }
    
    [_player pause];

    [self removeObserverAndNotificationCenter];

    AVPlayerItem *nextItem= [[AVPlayerItem alloc]initWithURL:[NSURL URLWithString:[self.arrPlayList[--_currentIndex] audio_src]]];
    
    [_player replaceCurrentItemWithPlayerItem:nextItem];
    
    [self addObserverAndNotificationCenter];
    
    [_player play];
    
    AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    
    if ([WShareUtil sharedData].arrPlayList >= 0 || [WShareUtil sharedData].arrPlayList != nil) {
        
        if (_currentIndex > [WShareUtil sharedData].arrPlayList.count || _currentIndex < 0) {
            return;
        }
       
        appDelegate.wWindow.playTool.lbPlayTit.titleStr = [[WShareUtil sharedData].arrPlayList[_currentIndex] strTitle];
        
    }
    
    [appDelegate.wWindow.playTool.lbPlayTit show];
    
}

#pragma mark 音频缓存和播放进度提示
- (void)playProgressAction{
    
    if (self.delegatePlayer && [self.delegatePlayer respondsToSelector:@selector(changeUIstateClicked:)]) {
        [self.delegatePlayer changeUIstateClicked:_player];
    }
    
}

- (void)playbackFinished:(NSNotification *)notice {
    WLog(@"播放完成");
    if ([WShareUtil sharedData].isHeartaxList) {
        [self audioPlayerPlayNext];
    }else {
        [self audioPlayerDestroy];

    }
}

- (void)onPlayBuffering:(NSNotification *)notice {
    WLog(@"-> onPlayBuffering\n");
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    
    
    dispatch_async(dispatch_get_main_queue(), ^{
        
        AVPlayerItem * songItem = object;

        if ([keyPath isEqualToString:@"status"]) {
            switch (self.player.status) {
                case AVPlayerStatusUnknown:
                    WLog(@"KVO：未知状态，此时不能播放");
                    break;
                case AVPlayerStatusReadyToPlay:
                    WLog(@"KVO：准备完毕，可以播放");
                    break;
                case AVPlayerStatusFailed:
                    WLog(@"KVO：加载失败，网络或者服务器出现问题");
                    break;
                default:
                    break;
            }
        }
        
        if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
            NSArray * array = songItem.loadedTimeRanges;
            CMTimeRange timeRange = [array.firstObject CMTimeRangeValue]; //本次缓冲的时间范围
            NSTimeInterval totalBuffer = CMTimeGetSeconds(timeRange.start) + CMTimeGetSeconds(timeRange.duration); //缓冲总长度
            WLog(@"共缓冲%.2f",totalBuffer);
            
            [WShareUtil sharedData].isPlay = YES;
        }
        
        if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {
            [SVProgressHUD dismiss];
        }
        
        if ([keyPath isEqualToString:@"playbackBufferEmpty"]) {
            WLog(@"缓冲数据为空，而且有效时间内数据无法补充，播放失败");
        }
        
        //    CMTime time = _player.currentItem.duration;
        //    Float64 seconds = CMTimeGetSeconds(time);
        //    WLog(@"%f +============",seconds);

    
    });
}

- (void)changeSliderValueClicked:(UISlider *)sender {
    
    [SVProgressHUD show];
    [SVProgressHUD setOffsetFromCenter:UIOffsetMake(0, WSCREENH_HEIGHT *0.5 - 334)];
    [SVProgressHUD setForegroundColor:[UIColor colorWithRed:0.06 green:0.71 blue:0.83 alpha:1]];
    
    CMTime time = _player.currentItem.duration;
    Float64 seconds = CMTimeGetSeconds(time);

    if ([_player.currentItem.asset tracksWithMediaType:AVMediaTypeAudio].count == 0) {
        return;
    }
    float fps = [[[_player.currentItem.asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] nominalFrameRate];
    
    double newSeekTime = (sender.value) * seconds;
    CMTime stime = CMTimeMakeWithSeconds(newSeekTime, fps);
    [_player seekToTime:stime];
}

- (void)audioPlayerSeekTime:(NSInteger)timeValue {
    
    CMTime time = _player.currentItem.currentTime;
    Float64 seconds = CMTimeGetSeconds(time);
    
    float fps = [[[_player.currentItem.asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] nominalFrameRate];
    
    CMTime stime = CMTimeMakeWithSeconds(seconds + timeValue, fps);

    [_player seekToTime:(stime)];
}

- (void)addObserverAndNotificationCenter {
    
    [_player.currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    [_player.currentItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
    [_player.currentItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
    [_player.currentItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:_player.currentItem];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onPlayBuffering:) name:AVPlayerItemPlaybackStalledNotification object:_player.currentItem];
}

- (void)removeObserverAndNotificationCenter {
    
    [_player.currentItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
    [_player.currentItem removeObserver:self forKeyPath:@"status"];
    [_player.currentItem removeObserver:self forKeyPath:@"playbackBufferEmpty"];
    [_player.currentItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];
    
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    
}

- (void)audioPlayerDestroy {
    
    [SVProgressHUD dismiss];

    [self removeObserverAndNotificationCenter];

    if (_currentItem) {
        _currentItem = nil;
    }
    
    if (_player) {
        _player = nil;
    }
    
    if (self.playerTimer) {
        
        [self.playerTimer invalidate];
        self.playerTimer = nil;
    }
    
    [WShareUtil sharedData].isPlay = NO;

}


-(void)dealloc
{
    [self removeObserverAndNotificationCenter];
}

@end
